﻿#include "MaterialDialogFE.h"
#include "ui_MaterialDialogFE.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterial.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"

#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialElastic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialDensity.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialExpansion.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialDamping.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialBehavior.h"

#include <QMessageBox>

namespace GUI
{
    MaterialDialogFE::MaterialDialogFE(PhysicsDlgExecType type, int matid /*= -1*/, QWidget* parent /*= nullptr*/)
        :AbstractMaterialDialog(type, parent)
    {
        _ui = new Ui::MaterialDialogFE;
        _ui->setupUi(this);

        _ui->tableWidget->clear();
        _ui->tableWidget->setColumnCount(0);
        _ui->tableWidget->setRowCount(0);
        QStringList headerLabels;
        //表头
        headerLabels << tr(" Field 1 ") << tr(" MID ") << tr(" Field 3 ") << tr(" Field 4 ") << tr(" Field 5 ") 
            << tr(" Field 6 ") << tr(" Field 7 ") << tr(" Field 8 ") << tr(" Field 9 ") << tr(" Field 10 ");
        //设置表格列数和表头标签
        _ui->tableWidget->setColumnCount(headerLabels.size());
        _ui->tableWidget->setHorizontalHeaderLabels(headerLabels);
        //初始化表格行数
        _ui->tableWidget->setRowCount(1);
        QTableWidgetItem* item = new QTableWidgetItem(tr("MAT1"));
        item->setFlags(item->flags() & ~Qt::ItemIsEditable); 
        _ui->tableWidget->setItem(0, 0, item);
        QTableWidgetItem* itemMID = new QTableWidgetItem();
        itemMID->setFlags(item->flags() & ~Qt::ItemIsEditable);
        _ui->tableWidget->setItem(0, 1, itemMID);

        Interface::FITKMaterialManager *feMgr = getFEMaterialManager();

        //获取FE材料对象
        if (feMgr && matid > 0) 
        {
            _feMat = dynamic_cast<Interface::FITKAbaMaterial*>(feMgr->getDataByID(matid));
            itemMID->setText(QString::number(matid));
        }
        this->init();
    }

    MaterialDialogFE::~MaterialDialogFE()
    {
        if (_ui) delete _ui;
    }

    void MaterialDialogFE::on_pushButton_Ok_clicked()
    {
        if (!this->checkInput()) return;
        //保存执行的脚本
        QStringList str;
        QString materialName = _ui->lineEdit_Name->text();
        //创建与复制,创建新对象
        if (_execType == GUI::PhysicsDlgExecType::Create || _execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            str.append("m=Material.FE()");
            str.append(QString("m.createMaterial('%1')").arg(materialName));

            _feMat = new Interface::FITKAbaMaterial;
            Interface::FITKMaterialManager *feMgr = getFEMaterialManager();
            if (feMgr == nullptr) return;
            feMgr->appendDataObj(_feMat);
        }
        if (!_feMat)return;
        //保存数据
        double E = getCellText(0, 2).toDouble();
      //double G = getCellText(0, 3).toDouble();
        double NU = getCellText(0, 4).toDouble();
        double RHO = getCellText(0, 5).toDouble();
        double A = getCellText(0, 6).toDouble();
        double TREF = getCellText(0, 7).toDouble();
        double GE = getCellText(0, 8).toDouble();
      //double G = E / (2 + 2 * NU);

        if (_execType == GUI::PhysicsDlgExecType::Edit)
        {
            str.append(QString("m=Material.FE.GetFE('%1')").arg(_feMat->getDataObjectName()));
            str.append(QString("m.setName('%1')").arg(materialName));
        }
        str.append(QString("m.setField(%1,%2)").arg(1).arg(E));
        //str.append(QString("m.setField(%1,%2)").arg(2).arg(molecular));
        str.append(QString("m.setField(%1,%2)").arg(3).arg(NU));
        str.append(QString("m.setField(%1,%2)").arg(4).arg(RHO));
        str.append(QString("m.setField(%1,%2)").arg(5).arg(A));
        str.append(QString("m.setField(%1,%2)").arg(6).arg(TREF));
        str.append(QString("m.setField(%1,%2)").arg(7).arg(GE));

        _feMat->setDataObjectName(materialName);
        // 添加并设置密度行为
        _feMat->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Density);
        Interface::FITKAbaMaterialDensity* densityBehavior = dynamic_cast<Interface::FITKAbaMaterialDensity*>(
            _feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Density));
        if (densityBehavior)
        {
            densityBehavior->setMassDensity(RHO);
        }
        // 添加并设置弹性行为
        _feMat->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Elastic);
        Interface::FITKAbaMaterialElastic* elasticBehavior = dynamic_cast<Interface::FITKAbaMaterialElastic*>(
            _feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Elastic));
        if (elasticBehavior)
        {
            elasticBehavior->setMaterialElasticType(Interface::FITKAbaMaterialBehaviorEnum::IsoTropic);
            elasticBehavior->setIsotropicYoungsModulus(E);
            elasticBehavior->setIsotropicPoissonRatio(NU);
        }
        // 添加并设置热膨胀行为
        _feMat->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Expansion);
        Interface::FITKAbaMaterialExpansion* expansionBehavior = dynamic_cast<Interface::FITKAbaMaterialExpansion*>(
            _feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Expansion));
        if (expansionBehavior)
        {
            expansionBehavior->setExpansionType(Interface::FITKAbaMaterialBehaviorEnum::Isotropic);
            expansionBehavior->setIsotropicTemperature(TREF);
            expansionBehavior->setIsoTropicExpansionCoeff(A);
        }
        // 添加并设置阻尼行为
        _feMat->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Damping);
        Interface::FITKAbaMaterialDamping* dampingBehavior = dynamic_cast<Interface::FITKAbaMaterialDamping*>(
            _feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Damping));
        if (dampingBehavior)
        {
            dampingBehavior->setStructural(GE);
        }
        this->saveScript(str);
        this->accept();
    }

    void MaterialDialogFE::on_pushButton_Cancel_clicked()
    {
        this->reject();
    }

    void MaterialDialogFE::init()
    {
        Interface::FITKMaterialManager *feMgr = getFEMaterialManager();
        if (feMgr == nullptr) return;
        if (_execType == GUI::PhysicsDlgExecType::Create)
        {
            QString name = feMgr->checkName("New FE Material");
            _ui->lineEdit_Name->setText(name);
        }
        // 初始化数据
        this->initData();

        //自适应宽度
        _ui->tableWidget->resizeColumnsToContents();
        // 设置每列的最小宽度为 100 像素
        for (int i = 0; i < _ui->tableWidget->columnCount(); ++i)
        {
            int currentWidth = _ui->tableWidget->columnWidth(i);
            if (currentWidth < 100)
                _ui->tableWidget->setColumnWidth(i, 100);
            else if (currentWidth > 350)
                _ui->tableWidget->setColumnWidth(i, 350);
        }

        //复制,更新名称
        if (_feMat && _execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            QString text = QString("Copy of %1").arg(_feMat->getDataObjectName());
            _ui->lineEdit_Name->setText(text);
        }

    }

    void MaterialDialogFE::initData()
    {
        double E = 0;
        double NU = 0;
        double RHO = 0;
        double A = 0;
        double TREF = 0;
        double GE = 0;
        double G = 0;

        if (_feMat) 
        {
            Interface::FITKAbaMaterialElastic* elasticBevior = dynamic_cast<Interface::FITKAbaMaterialElastic*>
                (_feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Elastic));
            if (elasticBevior)
            {
                E = elasticBevior->getIsotropicYoungsModulus();
                NU = elasticBevior->getIsotropicPoisssonRatio();
                G = E / (2 + 2 * NU);
            }
            Interface::FITKAbaMaterialDensity* densityBehavior = dynamic_cast<Interface::FITKAbaMaterialDensity*>
                (_feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Density));
            if (nullptr != densityBehavior)
            {
                RHO = densityBehavior->getMassDensity();
            }
            Interface::FITKAbaMaterialExpansion* expensionBehavior = dynamic_cast<Interface::FITKAbaMaterialExpansion*>
                (_feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Expansion));
            if (nullptr != expensionBehavior)
            {
                TREF = expensionBehavior->getIsotropicTemperature();
                A = expensionBehavior->getIsotropicExpansionCoeff();
            }
            Interface::FITKAbaMaterialDamping* dampingBehavior = dynamic_cast<Interface::FITKAbaMaterialDamping*>
                (_feMat->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Damping));
            if (nullptr != dampingBehavior)
            {
                GE = dampingBehavior->getStructural();
            }
            _ui->lineEdit_Name->setText(_feMat->getDataObjectName());
        }

        _ui->tableWidget->setItem(0, 2, new QTableWidgetItem(QString::number(E)));

        QTableWidgetItem* item3 = new QTableWidgetItem(QString::number(G));
        item3->setFlags(item3->flags() & ~Qt::ItemIsEditable);  

        _ui->tableWidget->setItem(0, 3, item3);
        _ui->tableWidget->setItem(0, 4, new QTableWidgetItem(QString::number(NU)));
        _ui->tableWidget->setItem(0, 5, new QTableWidgetItem(QString::number(RHO)));
        _ui->tableWidget->setItem(0, 6, new QTableWidgetItem(QString::number(A)));
        _ui->tableWidget->setItem(0, 7, new QTableWidgetItem(QString::number(TREF)));
        _ui->tableWidget->setItem(0, 8, new QTableWidgetItem(QString::number(GE)));
        QTableWidgetItem* item9 = new QTableWidgetItem("");
        item9->setFlags(item9->flags() & ~Qt::ItemIsEditable);  
        _ui->tableWidget->setItem(0, 9, item9);
    }

    bool MaterialDialogFE::checkInput()
    {
        //检查数据合法性
        for (int i = 2; i < _ui->tableWidget->columnCount()-2;++i)
        {
            QString text = getCellText(0,i);
            bool ok = false;
            text.toDouble(&ok);
            if (!ok)
            {
                QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a number."));
                return false;
            }
        }
        Interface::FITKMaterialManager *feMgr = getFEMaterialManager();
        if (feMgr == nullptr) return false;
        //检查名称
        QString text = _ui->lineEdit_Name->text().trimmed();
        if (text != "") {
            QString newText = feMgr->checkName(text);
            if (text == newText) return true;
            //与自己重名
            if (feMgr->getDataByName(text) == _feMat) return true;
        }
        QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a new Name."));
        return false;
    }

    Interface::FITKMaterialManager * MaterialDialogFE::getFEMaterialManager()
    {
        //获取材料管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return nullptr;
        Acoustics::FITKAcousticsFEModel* feModel = disc->getFEModel();
        if (!feModel) return nullptr;
        return feModel->getMaterialManager();
    }

    QString MaterialDialogFE::getCellText(int row, int col)
    {
        QTableWidgetItem* item = _ui->tableWidget->item(row, col);
        if (item)
            return item->text();
        return QString();
    }
}

